package com.sahyadri.web.util.tags;

import java.io.IOException;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.tags.MessageTag;

/**
 * This tag will display an inline message div with either a success or error message.
 * To determine if a message will be displayed as success or error, you can set the messageType attribute to "success" or "error".
 * Alternatively, you can leave the messageType attribute blank in which case this class will try to determine the messageType based on the message code. 
 * The code will be resolved to a message using Springs message code resolution functionality.
 * @see ServerSideStatusMessageTag#getMessageTypeFromCode(String) 
 * @author 
 *
 */
public class ServerSideStatusMessageTag extends MessageTag {

	private static final String DEFAULT_CONTENT_CSS_CLASS = "status-message-content";
	private static final String DEFAULT_ID = "status-message";
	private static final String STATUS_SUCCESS = "success";
	private static final String STATUS_ERROR = "error";
		
	//Set the default values for the optional tag values
	private String messageContentCssClass = DEFAULT_CONTENT_CSS_CLASS;
	private String messageCode;
	private String messageType;
	private String style;
	
	public ServerSideStatusMessageTag(){
		// Setting text to blank prevents tag from blowing up when no code is specified.
		super.setId(DEFAULT_ID);
		super.setText(" ");
	}
	
	@Override
	protected void writeMessage(String msg) throws IOException {
		
		
		if (!StringUtils.hasText(msg)) {
			// Only write out tag contents if there's a message to display.
			return;
		}
		
		String newline = System.getProperty("line.separator");
		StringBuilder sb = new StringBuilder();
		
		// If user specified messageType, use that, else derive it from the message code
		String msgType = (this.messageType != null) ? this.messageType : getMessageTypeFromCode(getMessageCode());
		sb.append(newline);
		sb.append("<div id=\"" + getId() + "\" class=\"status-message-" + msgType + "-main\" style=\"" + style + "\">" + newline);
		sb.append("  <span id=\""+ getId()+ "Content\" class=\"" + getMessageContentCssClass() + "\">" + msg + "</span>" + newline);
		sb.append("  <div id=\"" +getId()+ "Left\" class=\"status-message-" + msgType + "-left\"></div>" + newline);
		sb.append("  <div id=\"" +getId()+ "Right\" class=\"status-message-" + msgType + "-right\"></div>" + newline);
		sb.append("</div>");
		super.writeMessage(sb.toString());
		
	}

	/**
	 * This method takes a period delimited messageCode and returns a messageType string based on the last section of the messageType code.
	 * A messageType code of "error" will be returned if the code ends with either "error" or "failure", otherwise "success" is returned.
	 * For example:
	 * 
	 * <ul>
	 * <li>document.save.error --> error
	 * <li>document.save.failure --> error
	 * <li>document.save.success --> success
	 * <li>document.save --> success
	 * @param messageCode Message code to be parsed out.
	 * @return String messageType indicator ("success" or "failure").
	 */
	private String getMessageTypeFromCode(String messageCode) {
		
		if (messageCode == null) {
			return STATUS_SUCCESS;
		}
		
		String[] messageCodeParts = getMessageCode().split("\\.");
		String msgTypePart = messageCodeParts[messageCodeParts.length - 1];
		if ("error".equalsIgnoreCase(msgTypePart) || "failure".equalsIgnoreCase(msgTypePart)) {
			return STATUS_ERROR;
		}
		
		return STATUS_SUCCESS;
	}

	public String getMessageContentCssClass() {
		return messageContentCssClass;
	}

	public void setMessageContentCssClass(String messageContentCssClass) {
		this.messageContentCssClass = messageContentCssClass;
	}

	public void setMessageCode(String messageCode) {
		super.setCode(messageCode);
		this.messageCode = messageCode;
	}

	public String getMessageCode() {
		return messageCode;
	}

	public void setMessageType(String type) {
	
		if (STATUS_ERROR.equalsIgnoreCase(type)) {
			this.messageType = STATUS_ERROR;
		}
		else if (STATUS_SUCCESS.equalsIgnoreCase(type)) {
			this.messageType = STATUS_SUCCESS;
		}
		else {
			throw new IllegalArgumentException("Invalid messageType ('" + type + "'). Only 'success' and 'error' are allowed.");
		}
	
	}

	public String getMessageType() {
		return messageType;
	}

	public void setStyle(String style) {
		this.style = style;
	}

	public String getStyle() {
		return style;
	}
	
}

